/**
 * Created by jinxs on 14-6-25.
 *  基于easyui.resizable
 */
(function ($) {

    var _cacheName = 'resizable';
    /**
     * @class 调整大小组件
     * @constructor resizable
     * @summary 构造函数
     * @param [options] {Object|String} 组件配置参数|要调用的组件方法名
     * @param [param] {Object} 表示要调用的组件方法的参数
     */
    $.fn.resizable = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.resizable.methods[options](this, param);
        }
        return this.each(function () {
            var me = $(this);
            var cache = me.data(_cacheName);

            options = options || {};
            if (cache) {
                me.unbind('.resizable');
                $.extend(cache.options, options);
            } else {
                options = $.extend({}, $.fn.resizable.defaults, me.parseUIConfig(), options);
                me.data(_cacheName, {options: options});
            }
            if (options.disabled == true) {
                return;
            }
            me.bind('mousemove.resizable', {target: me}, function (e) {
                if ($.fn.resizable.isResizing) {
                    return;
                }
                _setCursor(e, _getDirection(e));
            }).bind('mouseleave.resizable', {target: me}, function (e) {
                _setCursor(e, '');
            })
            .bind('mousedown.resizable', {target: me}, function (e) {
                var dir = _getDirection(e);
                _setCursor(e, dir);
                if (dir == '') return;
                var targ = $(e.data.target);
                var data = {
                    target: targ,
                    parent: targ.parent()[0],
                    dir: dir,
                    startLeft: _getCssValue(e, 'left'),
                    startTop: _getCssValue(e, 'top'),
                    left: _getCssValue(e, 'left'),
                    top: _getCssValue(e, 'top'),
                    startX: e.pageX,
                    startY: e.pageY,
                    startWidth: targ.outerWidth(),
                    startHeight: targ.outerHeight(),
                    width: targ.outerWidth(),
                    height: targ.outerHeight(),
                    deltaWidth: targ.outerWidth() - targ.width(),
                    deltaHeight: targ.outerHeight() - targ.height()
                };
                $(document).bind('mousedown.resizable', data, _doDown);
                $(document).bind('mousemove.resizable', data, _doMove);
                $(document).bind('mouseup.resizable', data, _doUp);
                $('body').css('cursor', dir + '-resize');
            });
        });
    };
    /**
     * 方法
     * @lends resizable.prototype
     */
    $.fn.resizable.methods = {
        /**
         * @summary 获得组件的配置对象
         * @name resizable#options
         * @function
         * @returns {Object} 组件的配置对象
         */
        options: function (target) {
            return $.data(target[0], _cacheName).options;
        },
        /**
         * 启用组件。
         * @name resizable#enable
         * @function
         * @example
         * $('#input').resizable("enable")
         */
        enable: function (target) {
            target.resizable({disabled: false});
            return target;
        },
        /**
         * 禁用组件。
         * @name resizable#disable
         * @function
         * @example
         * $('#input').resizable("disable")
         */
        disable: function (target) {
            target.resizable({disabled: true});
            return target;
        }
    };
    /**
     * 默认配置
     * @lends resizable.prototype
     */
    $.fn.resizable.defaults = {
        /**
         * 是否禁用组件。
         * @default false
         * @type Boolean
         * @example
         * $('#input').disabled({disabled:false});
         */
        disabled: false,
        /**
         * @type ""
         * @default n, e, s, w, ne, se, sw, nw, all
         * @summary 调整大小时可拖动的范围
         */
        handles: 'n, e, s, w, ne, se, sw, nw, all',
        /**
         * @type Number
         * @default 10
         * @summary 组件的最小宽度
         */
        minWidth: 10,
        /**
         * @type Number
         * @default 10
         * @summary 组件的最小高度度
         */
        minHeight: 10,
        /**
         * @type Number
         * @default 10000
         * @summary 组件的最大宽度
         */
        maxWidth: 10000, //$(document).width(),
        /**
         * @type Number
         * @default 10000
         * @summary 组件的最大高度
         */
        maxHeight: 10000, //$(document).height(),
        /**
         * @type Number
         * @default 5
         * @summary handles的宽度
         */
        edge: 5,
        /**
         * @summary 在开始调整大小时触发的方法
         * @name resizable#onStartResize
         * @event
         * @default emptyFn
         */
        onStartResize: function (e) {
        },
        /**
         * @summary 在调整大小时触发的方法
         * @name resizable#onResize
         * @event
         * @default emptyFn
         */
        onResize: function (e) {
        },
        /**
         * @summary 在结束调整大小时触发的方法
         * @name resizable#onStopResize
         * @event
         * @default emptyFn
         */
        onStopResize: function (e) {
        }
    };

    $.fn.resizable.isResizing = false;

    var _resize = function (e) {
        var resizeData = e.data;
        var options = $.data(resizeData.target[0], _cacheName).options;
        if (resizeData.dir.indexOf('e') != -1) {
            var width = resizeData.startWidth + e.pageX - resizeData.startX;
            width = Math.min(
                Math.max(width, options.minWidth),
                options.maxWidth
            );
            resizeData.width = width;
        }
        if (resizeData.dir.indexOf('s') != -1) {
            var height = resizeData.startHeight + e.pageY - resizeData.startY;
            height = Math.min(
                Math.max(height, options.minHeight),
                options.maxHeight
            );
            resizeData.height = height;
        }
        if (resizeData.dir.indexOf('w') != -1) {
            var width = resizeData.startWidth - e.pageX + resizeData.startX;
            width = Math.min(
                Math.max(width, options.minWidth),
                options.maxWidth
            );
            resizeData.width = width;
            resizeData.left = resizeData.startLeft + resizeData.startWidth - resizeData.width;
        }
        if (resizeData.dir.indexOf('n') != -1) {
            var height = resizeData.startHeight - e.pageY + resizeData.startY;
            height = Math.min(
                Math.max(height, options.minHeight),
                options.maxHeight
            );
            resizeData.height = height;
            resizeData.top = resizeData.startTop + resizeData.startHeight - resizeData.height;
        }
    }

    var _applySize = function (e) {
        var resizeData = e.data;
        var t = $(resizeData.target);
        t.css({
            left: resizeData.left,
            top: resizeData.top
        });
        if (t.outerWidth() != resizeData.width) {
            t.outerWidth(resizeData.width)
        }
        if (t.outerHeight() != resizeData.height) {
            t.outerHeight(resizeData.height)
        }
    }

    var _doDown = function (e) {
        $.fn.resizable.isResizing = true;
        $.data(e.data.target[0], _cacheName).options.onStartResize.call(e.data.target, e);
        return false;
    }

    var _doMove = function (e) {
        _resize(e);
        if ($.data(e.data.target[0], _cacheName).options.onResize.call(e.data.target, e) != false) {
            _applySize(e)
        }
        return false;
    }

    var _doUp = function (e) {
        $.fn.resizable.isResizing = false;
        _resize(e, true);
        if ($.data(e.data.target[0], _cacheName).options.onStopResize.call(e.data.target, e) != false) {
            _applySize(e);
        }
        $(document).unbind('.resizable');
        $('body').css('cursor', '');
        return false;
    }

    var _getDirection = function (e) {
        var tt = $(e.data.target);
        var opts = $.data(e.data.target[0], _cacheName).options;
        var dir = '';
        var offset = tt.offset();
        var width = tt.outerWidth();
        var height = tt.outerHeight();
        var edge = opts.edge;
        if (e.pageY > offset.top && e.pageY < offset.top + edge) {
            dir += 'n';
        } else if (e.pageY < offset.top + height && e.pageY > offset.top + height - edge) {
            dir += 's';
        }
        if (e.pageX > offset.left && e.pageX < offset.left + edge) {
            dir += 'w';
        } else if (e.pageX < offset.left + width && e.pageX > offset.left + width - edge) {
            dir += 'e';
        }

        var handles = opts.handles.split(',');
        for (var i = 0; i < handles.length; i++) {
            var handle = handles[i].replace(/(^\s*)|(\s*$)/g, '');
            if (handle == 'all' || handle == dir) {
                return dir;
            }
        }
        return '';
    }
    var _getCssValue = function (e, css) {
        var val = parseInt($(e.data.target).css(css));
        if (isNaN(val)) {
            return 0;
        } else {
            return val;
        }
    }
    var _setCursor = function (e, dir) {
        if (dir == '') {
            $(e.data.target).css('cursor', '');
        } else {
            $(e.data.target).css('cursor', dir + '-resize');
        }
    }
})(jQuery);
